package com.iflyings.android.component

import org.json.JSONObject
import org.junit.Test

import org.junit.Assert.*

/**
 * Example local unit test, which will execute on the development machine (host).
 *
 * See [testing documentation](http://d.android.com/tools/testing).
 */
class ExampleUnitTest {
    @Test
    fun addition_isCorrect() {
        assertEquals(4, 2 + 2)
    }

    open class TestComponent(name: String): ComponentElement(name) {
        var isOpened = false

        override fun open() {
            isOpened = true
        }
        override fun close() {
            isOpened = false
        }

        override fun command(cmd: String, data: JSONObject): JSONObject {
            return data
        }
    }

    class Test1Component: TestComponent("test1")

    class Test2Component: TestComponent("test2")

    class Test3Component: TestComponent("test3")

    class Test4Component: TestComponent("test4")

    class Test5Component: TestComponent("test5")

    class Test6Component: TestComponent("test2")

    private fun checkName(context: ComponentContext, names: Array<String>) {
        var i = 0
        context.forEach { assertEquals(it.key.name, names[i++]) }
    }

    @Test
    fun test_component() {
        val t1 = Test1Component()
        val t2 = Test2Component()
        val t3 = Test3Component()
        val t4 = Test4Component()
        val t5 = Test5Component()
        val t6 = Test6Component()
        var c = t1 + t2 + t3

        c.forEach { it.open() }
        assertEquals(t1.isOpened, true)
        assertEquals(t2.isOpened, true)
        assertEquals(t3.isOpened, true)
        c.forEach { it.close() }

        c += t5 + t6 + t4
        c.forEach { it.open() }
        assertEquals(t1.isOpened, true)
        assertEquals(t2.isOpened, false)
        assertEquals(t3.isOpened, true)
        assertEquals(t4.isOpened, true)
        assertEquals(t5.isOpened, true)
        assertEquals(t6.isOpened, true)
        checkName(c, arrayOf("test1","test3","test5","test2","test4"))
        c.forEach { it.close() }

        c -= (t1 + t2 + t3)
        c.forEach { it.open() }
        assertEquals(t1.isOpened, false)
        assertEquals(t2.isOpened, false)
        assertEquals(t3.isOpened, false)
        assertEquals(t4.isOpened, true)
        assertEquals(t5.isOpened, true)
        assertEquals(t6.isOpened, false)
        checkName(c, arrayOf("test5","test4"))
        c.forEach { it.close() }

        c += t1 + t5 + t6 + t2
        c -= (t4 + t1)
        c.forEach { it.open() }
        assertEquals(t1.isOpened, false)
        assertEquals(t2.isOpened, true)
        assertEquals(t3.isOpened, false)
        assertEquals(t4.isOpened, false)
        assertEquals(t5.isOpened, true)
        assertEquals(t6.isOpened, false)
        checkName(c, arrayOf("test5","test2"))
        c.forEach { it.close() }

        assertEquals(c["test2"]?.key?.name, "test2")
        assert(c.get<Test2Component>()?.key?.name == "test2")
        assert(c.get<Test6Component>()?.key?.name == null)
        c += t6
        assertEquals(c["test2"]?.key?.name, "test2")
        assert(c.get<Test2Component>()?.key?.name == null)
        assert(c.get<Test6Component>()?.key?.name == "test2")
    }
}